package ca.ericslandry.client.mvp.presenter;

import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.place.Place;
import net.customware.gwt.presenter.client.place.PlaceRequest;
import ca.ericslandry.client.GwtCallback;
import ca.ericslandry.client.resource.MyConstants;
import ca.ericslandry.shared.domain.Issue;
import ca.ericslandry.shared.event.IssueSavedEvent;
import ca.ericslandry.shared.rpc.GenericResult;
import ca.ericslandry.shared.rpc.GetIssue;
import ca.ericslandry.shared.rpc.GetIssueResult;
import ca.ericslandry.shared.rpc.SaveIssue;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HasHTML;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.inject.Inject;

public class IssuePresenter extends BasePresenter<IssuePresenter.Display> {

	public interface Display extends BaseDisplay {
		HasClickHandlers getSave();

		HasValue<String> getTitleValue();

		HasHTML getDescription();

		HasValue<String> getGeohash();

		void createIssue();

		void showIssue(Issue issue);
	}

	public static final Place PLACE = new Place("issue");
	private DispatchAsync dispatcher;
	private ContentPresenter contentPresenter;

	@Inject
	public IssuePresenter(final Display display, final EventBus eventBus, DispatchAsync dispatcher,
			ContentPresenter contentPresenter) {
		super(display, eventBus);
		this.dispatcher = dispatcher;
		this.contentPresenter = contentPresenter;
		bind();
	}

	@Override
	protected void onBind() {
		Log.debug("onBind: issue");
		// ACTION: save issue
		registerHandler(display.getSave().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				saveIssue();
			}
		}));
	}

	private void saveIssue() {
		Issue issue = new Issue();
		issue.setTitle(display.getTitleValue().getValue());
		issue.setDescription(display.getDescription().getHTML());
		issue.setGeohash(display.getGeohash().getValue());
		dispatcher.execute(new SaveIssue(issue), new GwtCallback<GenericResult>(dispatcher, eventBus, display) {
			@Override
			public void callback(GenericResult result) {
				if (result.isSuccess()) {
					eventBus.fireEvent(new IssueSavedEvent());
				} else {
					Window.alert("Fail whale");
				}
			}
		});
	}

	public void createIssue() {
		if (UserPresenter.isLoggedin()) {
			contentPresenter.getDisplay().setContent(this.display.asWidget());
			display.createIssue();
		} else {
			Window.alert(MyConstants.INSTANCE.needToBeLoggedIn());
		}
	}

	public void showIssue(Issue issue) {
		contentPresenter.getDisplay().setContent(this.display.asWidget());
		display.showIssue(issue);
	}

	private void showIssue(Long id) {
		dispatcher.execute(new GetIssue(id), new GwtCallback<GetIssueResult>(dispatcher, eventBus, display) {
			@Override
			public void callback(GetIssueResult result) {
				Issue issue = result.getIssue();
				showIssue(issue);
			}
		});
	}

	@Override
	public Place getPlace() {
		return PLACE;
	}

	@Override
	protected void onPlaceRequest(PlaceRequest placeReq) {
		String action = placeReq.getParameter(ACTION, null);
		if (CREATE.equalsIgnoreCase(action)) {
			Log.info("onPlaceRequest: create issue");
			createIssue();
		} else if (VIEW.equalsIgnoreCase(action)) {
			Long id = Long.parseLong(placeReq.getParameter(ID, "0"));
			if (id != 0) {
				Log.info("onPlaceRequest: show issue " + id);
				showIssue(id);
			}
		}
	}

	public static Hyperlink getLinkCreateIssue() {
		PlaceRequest placeReq = new PlaceRequest(PLACE).with(ACTION, CREATE);
		return new Hyperlink(MyConstants.INSTANCE.newIssue(), placeReq.toString());
	}

	public static Hyperlink getLinkViewIssue(Issue issue) {
		PlaceRequest placeReq = new PlaceRequest(PLACE).with(ACTION, VIEW).with(ID, String.valueOf(issue.getId()));
		return new Hyperlink(issue.getTitle(), placeReq.toString());
	}
}
